#include "ProcessOrder.h"

ORDER_LIST  g_OrderList;
DEVICE_LIST g_FreeDeviceLsit;
/****************************
Function   :
Parameter  :
ReturnValue:
Author     :
Data       :
****************************/
ProcessOrder::ProcessOrder()
{
    pthread_mutex_init(&m_mutex_OrderList , NULL);
    pthread_mutex_init(&m_mutex_FreeDeviceLsit , NULL);
    m_pMySql = new MySql_DB(SERVER_IP,USER_NAME , PASSWORD);
}
/****************************
Function   :
Parameter  :
ReturnValue:
Author     :
Data       :
****************************/
ProcessOrder::~ProcessOrder()
{
   pthread_mutex_destroy(&m_mutex_OrderList);
   pthread_mutex_destroy(&m_mutex_FreeDeviceLsit);
   delete m_pMySql;
}
/****************************
Function   :
Parameter  :
ReturnValue:
Author     :
Data       :
****************************/
bool ProcessOrder::start()
{
      if(!m_pMySql->ConnectToServer(DATABASE))
      {
        return false;
      }

//      pthread_t Pid_creat;
//      if(pthread_create(&Pid_creat,NULL,&threadCheckOrderFormDB,this))
//      {
//         LOG(ERROR) << "Thread Creat Failed";          //日志
//         google::ShutdownGoogleLogging();              // 停止GLog
//         return false;
//      }

       pthread_t Pid_send;
      if(pthread_create(&Pid_send,NULL,&threadSendOrders,this))
      {
         LOG(ERROR) << "Thread Creat Failed";          //日志
         google::ShutdownGoogleLogging();              // 停止GLog
         return false;
      }

      return true;
}
///****************************
//Function   :
//Parameter  :
//ReturnValue:
//Author     :
//Data       :
//****************************/
//void *threadCheckOrderFormDB(void*p)
//{
//  ProcessOrder *pProcessOrder = (ProcessOrder*)p;
//  pProcessOrder->CheckOrderFormDB();
//  return 0;
//}
//void ProcessOrder::CheckOrderFormDB()
//{
//      pthread_mutex_lock(&m_mutex_OrderList);
//      m_pMySql->GetOrder(OrderState_NotProcess , g_OrderList);
//      m_pMySql->GetOrder(OrderState_WaitForProcess , g_OrderList);
//      pthread_mutex_unlock(&m_mutex_OrderList);
////    while(1)
////    {
////      sleep(10);
////      pthread_mutex_lock(&m_mutex_OrderList);
////      m_pMySql->GetOrder(OrderState_NotProcess , g_OrderList);
////      pthread_mutex_unlock(&m_mutex_OrderList);
////    }
//}
/****************************
Function   :
Parameter  :
ReturnValue:
Author     :
Data       :
****************************/
void *threadSendOrders(void*p)
{
  ProcessOrder *pProcessOrder = (ProcessOrder*)p;
  pProcessOrder->SendOrders();
  return 0;
}
void ProcessOrder::SendOrders()
{
      pthread_mutex_lock(&m_mutex_OrderList);
      m_pMySql->GetOrder(OrderState_NotProcess , g_OrderList);
      m_pMySql->GetOrder(OrderState_WaitForProcess , g_OrderList);
      pthread_mutex_unlock(&m_mutex_OrderList);

    while(1)
    {
      sleep(5);

       pthread_mutex_lock(&m_mutex_OrderList);
       pthread_mutex_lock(&m_mutex_FreeDeviceLsit);

       m_pMySql->GetDevice(DeviceState_Free , g_FreeDeviceLsit);
       m_pMySql->GetOrder(OrderState_NotProcess , g_OrderList);

       int nNumberOfOrder = g_OrderList.size();
       int nNumberOfFreeList = g_FreeDeviceLsit.size();

        pthread_mutex_unlock(&m_mutex_OrderList);
        pthread_mutex_unlock(&m_mutex_FreeDeviceLsit);


       printf("NumberOfOrder   : %d\r\n",nNumberOfOrder);
       printf("NumberOfFreeDevice   : %d\r\n",nNumberOfFreeList);
       if(nNumberOfOrder == 0 || nNumberOfFreeList == 0)
       {
         continue;
       }

       LOG(INFO) << "Number of free Order " << nNumberOfOrder;
       LOG(INFO) << "Number of free Device" << nNumberOfFreeList;

        pthread_t Pid_monitor;
          if(pthread_create(&Pid_monitor,NULL,&threadMonitorOrders,this))
          {
             LOG(ERROR) << "Thread Creat Failed";          //日志
             continue;
          }
    }
}
/****************************
Function   :
Parameter  :
ReturnValue:
Author     :
Data       :
****************************/
void *threadMonitorOrders(void*p)
{
  ProcessOrder *pProcessOrder = (ProcessOrder*)p;
  pProcessOrder->MonitorOrders();
  return 0;
}
void ProcessOrder::MonitorOrders()
{
       LOG(INFO) << "Now Start Process Order:";
       char cReceiveBuf[MESSAGE_LENGTH];
       string strRecv;
       memset(cReceiveBuf,0,MESSAGE_LENGTH);

       pthread_mutex_lock(&m_mutex_OrderList);
       pthread_mutex_lock(&m_mutex_FreeDeviceLsit);

       OrderForm  orderform(g_OrderList[0]);
       DeviceNode device(g_FreeDeviceLsit[0]);

       LOG(INFO) << "Device Id : " << device.DeviceID;
       LOG(INFO) << "Order Id : " << orderform.strOrderID;

       m_pMySql->SetDeviceStateById(device.DeviceID, DeviceState_Busy);

       g_OrderList.erase(g_OrderList.begin());
       g_FreeDeviceLsit.erase(g_FreeDeviceLsit.begin());

        pthread_mutex_unlock(&m_mutex_OrderList);
        pthread_mutex_unlock(&m_mutex_FreeDeviceLsit);


       string strSend =  "neworder" ;
              strSend += "|";
              strSend +=  orderform.strOrderID ;
              strSend += "|";
              strSend +=  orderform.strTime ;
              strSend += "|";
              strSend +=  orderform.strNumber ;
              strSend += "|";
              strSend +=  orderform.strLength ;
              strSend += "|";
              strSend +=  orderform.strWidth ;
              strSend += "|";
              strSend +=  orderform.strThickness ;
              strSend += "|";
              strSend +=  orderform.strThreshold ;
              memset(device.Sendbuf , 0 , MESSAGE_LENGTH);
              strcpy(device.Sendbuf,strSend.c_str());

              if(SocketSend( device.new_fd ,device.Sendbuf,MESSAGE_LENGTH) == FALSE)
            {
                LOG(ERROR) << "send error";
                m_pMySql->SetDeviceStateById(device.DeviceID, DeviceState_Offline);
                return ;
            }
              usleep(200*1000);
              if(SocketReceive( device.new_fd ,cReceiveBuf,MESSAGE_LENGTH) == FALSE)
              {
                LOG(ERROR) << "recv error";
                m_pMySql->SetDeviceStateById(device.DeviceID, DeviceState_Offline);
                return ;
              }
              strRecv = cReceiveBuf;
              if(strRecv != "ack\r\n")
              {
                 LOG(ERROR) << "device is not ok";
                 close(device.new_fd);
                 return ;
              }

        while(1)
        {
            sleep(5);
//            memset(device.Sendbuf, 0 , MESSAGE_LENGTH);
//
//             if(SocketSend( device.new_fd ,SendOrder[ORDEROK],MESSAGE_LENGTH) == FALSE)
//            {
//                LOG(ERROR) << "send error";
//                m_pMySql->SetDeviceStateById(device.DeviceID, DeviceState_Offline);
//                return ;
//            }
//           usleep(200*1000);
//           if(SocketReceive( device.new_fd ,cReceiveBuf,MESSAGE_LENGTH) == FALSE)
//           {
//             LOG(ERROR) << "recv error";
//             m_pMySql->SetDeviceStateById(device.DeviceID, DeviceState_Offline);
//             return ;
//           }
          strSend = "nowstate";
          strSend += "|";
          string strThreshold = m_pMySql->GetThresholdById(orderform.strOrderID);
          if(strThreshold.length() == 0)
          {
            LOG(ERROR) << "DbError";
            return ;
          }
          strSend += strThreshold;
              memset(device.Sendbuf , 0 , MESSAGE_LENGTH);
              strcpy(device.Sendbuf,strSend.c_str());

              if(SocketSend( device.new_fd ,device.Sendbuf,MESSAGE_LENGTH) == FALSE)
            {
                LOG(ERROR) << "send error";
                m_pMySql->SetDeviceStateById(device.DeviceID, DeviceState_Offline);
                return ;
            }
              usleep(200*1000);
              if(SocketReceive( device.new_fd ,cReceiveBuf,MESSAGE_LENGTH) == FALSE)
              {
                LOG(ERROR) << "recv error";
                m_pMySql->SetDeviceStateById(device.DeviceID, DeviceState_Offline);
                return ;
              }
              strRecv = cReceiveBuf;
              if(strRecv == "ok\r\n")
              {
                 LOG(ERROR) << "order is processed ok!";
                 m_pMySql->SetDeviceStateById(device.DeviceID, DeviceState_Free);
                 m_pMySql->SetOrderStateById(orderform.strOrderID , OrderState_IsProcessed);
                 return ;
              }
              else if(strRecv == "ack\r\n")
                {

                }
                else
                    {
                        LOG(ERROR) << "recv error";
                        close(device.new_fd);
                        m_pMySql->SetDeviceStateById(device.DeviceID, DeviceState_Offline);
                        return ;
                    }
        }
}
